package net.pzc.filechooser;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.TableColumn;

import net.pzc.log.ILiteLogger;
import net.pzc.log.LoggerFactory;
import net.pzc.log.SimpleLogger;
import net.pzc.resource.FFCResource;

public class FastFileChooser extends JPanel {
	private static ILiteLogger logger = LoggerFactory.getLogger(FastFileChooser.class); // @jve:decl-index=0:

	public static final int MODE_FILE = 1;
	public static final int MODE_FOLDER = 2;

	private static final long serialVersionUID = 1L;

	private static final int ERROR_OPTION = JOptionPane.CLOSED_OPTION;
	private static final int CANCEL_OPTION = JOptionPane.CANCEL_OPTION;

	private JDialog dialog = null;
	private int returnValue = ERROR_OPTION;
	
	private int mode = MODE_FILE;

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {

			public void run() {
				SimpleLogger.setLogLevel(SimpleLogger.LV_DEBUG);
				try {
					UIManager.put("ScrollPane.border", BorderFactory.createEmptyBorder());
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				} catch (Exception ex) {
					ex.printStackTrace();
				}
				JFrame j = new JFrame();
				j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				j.setLocation(400, 300);
				j.setVisible(true);
				FastFileChooser frame = new FastFileChooser();
				frame.addChoosableFileFilter(new FileFilter() {

					public boolean accept(File pathname) {
						return pathname.getAbsolutePath().endsWith(".xls");
					}

					@Override
					public String toString() {
						return "xls";
					}
				});
				frame.showOpenDialog(j);
				// JFileChooser f = new JFileChooser();
				// f.showOpenDialog(j);
			}

		});
	}

	private String initPath;
	private JComboBox cmb = null;
	private JButton btn_up = null;
	private String selectedAbsolutePath = null; // @jve:decl-index=0:
	private List<FileFilter> fileFilters = new ArrayList<FileFilter>(); // @jve:decl-index=0:

	public FastFileChooser() {
		this("");
	}

	public FastFileChooser(int mode) {
		this(mode, "");
	}

	public FastFileChooser(String initPath) {
		this(MODE_FILE, initPath);
	}

	public FastFileChooser(int mode, String initPath) {
		this.mode = mode;
		this.initPath = (initPath == null ? "" : initPath);
	}

	public int getMode() {
		return mode;
	}

	public int showOpenDialog(Frame frame) {
		this.initialize();
		return showDialogImpl(frame, 0);
	}

	protected int showDialogImpl(Frame parent, int i) {
		dialog = createDialog(parent);
		dialog.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				returnValue = CANCEL_OPTION;
			}
		});
		returnValue = ERROR_OPTION;

		this.initItems();

		dialog.setVisible(true);
		dialog.removeAll();
		dialog.dispose();
		dialog = null;
		return returnValue;
	}

	protected void closeDialog() {
		dialog.setVisible(false);
	}

	protected JDialog createDialog(Frame parent) throws HeadlessException {
		Frame frame1 = parent == null ? JOptionPane.getRootFrame() : parent;

		JDialog dialog = new JDialog(frame1, true);
		dialog.setTitle(FFCResource.get(FFCResource.DIALOG_TITLE_OPEN));
		dialog.setSize(new Dimension(600, 400));
		dialog.setComponentOrientation(this.getComponentOrientation());

		// dialog.setContentPane(this);
		Container contentPane = dialog.getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(this, BorderLayout.CENTER);

		dialog.setLocationRelativeTo(parent);

		return dialog;
	}

	private void initItems() {
		pcFlg = true;
		ListRootsAction lAction = new ListRootsAction(getCmb(), this.initPath, this);
		lAction.start();

		ListUserHomeAction luAction = new ListUserHomeAction(getJpUserHome());
		luAction.start();
	}

	private ListFilesAction rescanAction = null;

	protected void rescanCurrentDirectory() {
		logger.debug("selectedAbsolutePath:" + this.selectedAbsolutePath);
		rescanAction = new ListFilesAction(getTableView(), this, this.selectedAbsolutePath);
		rescanAction.start();
	}

	public void initialize() {

		this.setLayout(new BorderLayout());

		add(getTopPanel(), BorderLayout.NORTH);
		add(getJpCenter(), BorderLayout.CENTER);
		add(getButtomPanel(), BorderLayout.SOUTH);

		KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE");
		Action actionListener = new AbstractAction() {
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent actionEvent) {
				dialog.dispose();
			}
		};
		InputMap inputMap = this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		inputMap.put(stroke, "ESCAPE");
		this.getActionMap().put("ESCAPE", actionListener);

	}

	private JPanel topPanel = null;
	private JPanel topButtonPanel = null;
	private JLabel lbl_folder = null;
	private JPanel topBorderPanel = null;

	private JPanel getTopPanel() {
		if (topPanel == null) {
			topPanel = new JPanel();
			topPanel.setLayout(new BorderLayout());
			topPanel.setSize(300, 60);

			topPanel.add(getLbl_folder(), BorderLayout.WEST);
			topPanel.add(getCmb(), BorderLayout.CENTER);
			topPanel.add(getTopButtonPanel(), BorderLayout.EAST);
			topPanel.add(getTopBorderPanel(), BorderLayout.SOUTH);
		}
		return topPanel;
	}

	private JLabel getLbl_folder() {
		if (lbl_folder == null) {
			lbl_folder = new JLabel(FFCResource.get(FFCResource.FOLDER_NAME));
			lbl_folder.setPreferredSize(new Dimension(99, 22));
		}
		return lbl_folder;
	}

	protected JComboBox getCmb() {
		if (cmb == null) {
			cmb = new JComboBox();
			cmb.setRenderer(new MyComboBoxRenderer(cmb));
			final DefaultComboBoxModel cmbModel = new DefaultComboBoxModel();
			cmb.setModel(cmbModel);

			cmb.addMouseListener(new MouseAdapter() {
				@Override
				public void mousePressed(MouseEvent mouseevent) {
					logger.debug("cmb.mousePressed ---- start");
					pcFlg = false;
					logger.debug(pcFlg);
					logger.debug("cmb.mousePressed ---- start");
				}
			});

			cmb.addItemListener(new ItemListener() {

				public void itemStateChanged(ItemEvent e) {
					if (e.getStateChange() == ItemEvent.SELECTED) {
						logger.debug("cmb.itemStateChanged ---- start");
						logger.debug(pcFlg);
						if (pcFlg == false) {
							// update listView
							FileItem item = (FileItem) e.getItem();
							setSelectedAbsolutePath(item.getAbsolutePath());
							updateUserHome();
							int i = cmbModel.getIndexOf(item);
							List<FileItem> removeList = new ArrayList<FileItem>();
							for (int j = i + 1; j < cmbModel.getSize(); j++) {
								FileItem tmpItem = (FileItem) cmbModel.getElementAt(j);
								if (tmpItem.getStep() != 0) {
									removeList.add(tmpItem);
								} else {
									break;
								}
							}
							for (FileItem tmpItem : removeList) {
								cmbModel.removeElement(tmpItem);
							}

							OpenFileAction action = new OpenFileAction(getTableView(), false, item.getAbsolutePath(),
									FastFileChooser.this, pcFlg);
							action.start();

						}
						pcFlg = false;
						logger.debug("cmb.itemStateChanged ---- end");
					}
				}

			});

		}
		return cmb;
	}

	private JPanel getTopButtonPanel() {
		if (topButtonPanel == null) {
			topButtonPanel = new JPanel();
			topButtonPanel.setLayout(null);
			topButtonPanel.setPreferredSize(new Dimension(100, 22));
			topButtonPanel.add(getBtn_up());
		}
		return topButtonPanel;
	}

	protected JButton getBtn_up() {
		if (btn_up == null) {

			ImageIcon icon = new ImageIcon(this.getClass().getResource("/img/folder_up.png"));
			btn_up = new JButton();
			btn_up.setIcon(icon);
			btn_up.setSize(new Dimension(26, 22));
			btn_up.setPreferredSize(new Dimension(26, 22));
			btn_up.setBorderPainted(false);
			btn_up.setContentAreaFilled(false);
			btn_up.setEnabled(false);
			btn_up.setFocusPainted(false);
			btn_up.setLocation(4, 4);

			btn_up.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseEntered(MouseEvent event) {
					JButton btn = (JButton) event.getSource();
					btn.setBorderPainted(true);
				}

				@Override
				public void mouseExited(MouseEvent event) {
					JButton btn = (JButton) event.getSource();
					btn.setBorderPainted(false);
				}
			});

			btn_up.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					FileItem parentItem = (FileItem) getCmb().getSelectedItem();
					if (parentItem.getStep() > 0) {
						getCmb().setSelectedIndex(getCmb().getSelectedIndex() - 1);
					}
				}

			});

		}
		return btn_up;
	}

	private JPanel getTopBorderPanel() {
		if (topBorderPanel == null) {
			topBorderPanel = new JPanel();
			topBorderPanel.setPreferredSize(new Dimension(100, 4));
		}
		return topBorderPanel;
	}

	// --------------------------------------------------------------------------

	private JPanel jpCenter = null;
	private JPanel jPanel_10 = null;
	private JPanel jPanel_10_left = null;
	private JPanel jPanel_10_right = null;
	private ToggleButtonGroupPanel jpUserHome = null;
	private JScrollPane filesScrollPane = null;
	private JList listView = null;
	private JTable tableView = null;

	private JPanel getJpCenter() {
		if (jpCenter == null) {
			jpCenter = new JPanel();
			jpCenter.setLayout(new BorderLayout());
			jpCenter.add(getJPanel_10(), BorderLayout.WEST);
			jpCenter.add(getFilesScrollPane(), BorderLayout.CENTER);
		}
		return jpCenter;
	}

	protected JPanel getJPanel_10() {
		if (jPanel_10 == null) {
			jPanel_10 = new JPanel();
			jPanel_10.setLayout(new BorderLayout());
			jPanel_10.setPreferredSize(new Dimension(100, 82));

			jPanel_10.add(getJPanel_10_left(), BorderLayout.WEST);
			jPanel_10.add(getJpUserHome(), BorderLayout.CENTER);
			jPanel_10.add(getJPanel_10_right(), BorderLayout.EAST);
		}
		return jPanel_10;
	}

	protected JPanel getJPanel_10_left() {
		if (jPanel_10_left == null) {
			jPanel_10_left = new JPanel();
			jPanel_10_left.setPreferredSize(new Dimension(4, 10));
		}
		return jPanel_10_left;
	}

	protected JPanel getJPanel_10_right() {
		if (jPanel_10_right == null) {
			jPanel_10_right = new JPanel();
			jPanel_10_right.setPreferredSize(new Dimension(4, 10));
		}
		return jPanel_10_right;
	}

	protected ToggleButtonGroupPanel getJpUserHome() {
		if (jpUserHome == null) {
			jpUserHome = new ToggleButtonGroupPanel();
			jpUserHome.setLayout(new GridLayout(3, 1));
			jpUserHome.setBorder(BorderFactory.createLoweredBevelBorder());
			jpUserHome.setPreferredSize(new Dimension(100, 82));

			jpUserHome.addToggleItemClickListener(new ToggleItemMouseListener() {

				public void onClick(JToggleButton btn, Object modelItem) {
//					logger.debug("jpUserHome.onClick ---- start");
//					FileItem sItem = (FileItem) modelItem;
//					//setSelectedAbsolutePath(sItem.getAbsolutePath());
//					openAction(sItem.getAbsolutePath());
//					logger.debug("jpUserHome.onClick ---- end");
				}

				public void onMousePressed(JToggleButton btn, Object modelItem) {
					logger.debug("jpUserHome.onClick ---- start");
					btn.setSelected(true);
					FileItem sItem = (FileItem) modelItem;
					//setSelectedAbsolutePath(sItem.getAbsolutePath());
					openAction(false, sItem.getAbsolutePath());
					logger.debug("jpUserHome.onClick ---- end");
				}

			});
		}
		return jpUserHome;
	}

	private JScrollPane getFilesScrollPane() {
		if (filesScrollPane == null) {
			filesScrollPane = new JScrollPane();
			filesScrollPane.setViewportView(getTableView());
			filesScrollPane.getViewport().setBackground(Color.white);
		}
		return filesScrollPane;
	}

	private JList getListView() {
		if (listView == null) {
			listView = new JList();
			listView.setCellRenderer(new MyListCellRender());
			listView.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			final DefaultListModel listViewModel = new DefaultListModel();
			listView.setModel(listViewModel);

			listView.addMouseListener(new MouseAdapter() {

				public void mouseClicked(MouseEvent e) {
					if (listView.isEnabled() == true) {
						FileItem fi = getSelectedItem(e, listView);
						if (fi != null) {
							if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
								OpenFileAction action = new OpenFileAction(getListView(), false, fi.getAbsolutePath(),
										FastFileChooser.this, pcFlg);
								action.start();
							}
							if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1) {
								File f = new File(fi.getAbsolutePath());
								getTxt_fileName().setText(f.getName());
							}
						}
					}
				}

			});

		}
		return listView;
	}

	private JTable getTableView() {
		if (tableView == null) {
			tableView = new JTable();
			tableView.setEnabled(false);
			tableView.getTableHeader().setPreferredSize(new Dimension(tableView.getTableHeader().getWidth(), 18));

			tableView.setDefaultRenderer(Object.class, new FileItemTableCellRenderer());
			Vector<Object> colList = new Vector<Object>();

			colList.add("Icon");
			colList.add("Name");
			colList.add("Size");
			colList.add("Type");
			colList.add("Datetime");

			final FileItemTableModel tableViewModel = new FileItemTableModel(colList);
			tableView.setModel(tableViewModel);

			tableView.setRowHeight(20);
			tableView.setShowGrid(false);
			// tableView.setShowVerticalLines(true);

			TableColumn tcIcon = tableView.getColumn("Icon");
			tcIcon.setHeaderValue("");
			tcIcon.setMaxWidth(20);
			tcIcon.setMinWidth(20);
			tcIcon.setResizable(false);

			TableColumn tcSize = tableView.getColumn("Size");
			// tcSize.setHeaderValue("");
			tcSize.setMaxWidth(60);
			tcSize.setMinWidth(60);

			tableView.addMouseListener(new MouseAdapter() {

				public void mousePressed(MouseEvent e) {
					logger.debug("tableView.mousePressed ---- start");
					if (tableView.isEnabled() == true) {
						FileItem fi = getSelectedItem(e, tableView);
						if (fi != null) {
							if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
								//setSelectedAbsolutePath(fi.getAbsolutePath());
								openAction(false, fi.getAbsolutePath());
							}
							if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1) {
								File f = new File(fi.getAbsolutePath());
								getTxt_fileName().setText(f.getName());
							}
						}
					}
					logger.debug("tableView.mousePressed ---- end");
				}

			});
		}
		return tableView;
	}

	// --------------------------------------------------------------------------------------

	private JPanel buttomPanel = null;
	private JPanel buttomNorthBorder = null;
	private JPanel buttomSouthBorder = null;

	private JPanel jPanel_11 = null;
	private JLabel lbl_fileName = null;
	private JLabel lbl_fileType = null;

	private JPanel jPanel_12 = null;
	private JPanel jPanel_13 = null;

	private JPanel jPanel_status = null;
	private JLabel lbl_status = null;
	private JProgressBar progressBar = null;

	private JPanel getButtomPanel() {
		if (buttomPanel == null) {
			buttomPanel = new JPanel();
			buttomPanel.setPreferredSize(new Dimension(100, 82));
			buttomPanel.setLayout(new BorderLayout());
			buttomPanel.add(getButtomNorthBorder(), BorderLayout.NORTH);
			buttomPanel.add(getButtomSouthBorder(), BorderLayout.SOUTH);
			buttomPanel.add(getJPanel_11(), BorderLayout.WEST);
			buttomPanel.add(getJPanel_12(), BorderLayout.CENTER);
			buttomPanel.add(getJPanel_13(), BorderLayout.EAST);

		}
		return buttomPanel;
	}

	private JPanel getButtomNorthBorder() {
		if (buttomNorthBorder == null) {
			buttomNorthBorder = new JPanel();
			buttomNorthBorder.setPreferredSize(new Dimension(100, 4));
		}
		return buttomNorthBorder;
	}

	private JPanel getButtomSouthBorder() {
		if (buttomSouthBorder == null) {
			buttomSouthBorder = new JPanel();
			buttomSouthBorder.setPreferredSize(new Dimension(80, 28));
			buttomSouthBorder.setLayout(new BorderLayout());
			buttomSouthBorder.add(getJPanel_status(), BorderLayout.CENTER);
		}
		return buttomSouthBorder;
	}

	private JPanel getJPanel_status() {
		if (jPanel_status == null) {
			jPanel_status = new JPanel();
			jPanel_status.setLayout(new BorderLayout());

			jPanel_status.add(getProgressBar(), BorderLayout.NORTH);
			jPanel_status.add(getLbl_status(), BorderLayout.CENTER);
			jPanel_status.add(getBtn_stopScan(), BorderLayout.EAST);
		}
		return jPanel_status;
	}

	protected JProgressBar getProgressBar() {
		if (progressBar == null) {
			progressBar = new JProgressBar(0, 0);
			progressBar.setPreferredSize(new Dimension(100, 15));
			progressBar.setStringPainted(true);
		}
		return progressBar;
	}

	private JButton btn_stopScan = null;

	private JButton getBtn_stopScan() {
		if (btn_stopScan == null) {
			// btn_stopScan = new JButton(FFCResource.get(FFCResource.CANCEL));
			btn_stopScan = new JButton("Stop");
			btn_stopScan.setSize(80, 20);
			btn_stopScan.setFocusPainted(false);
			btn_stopScan.setMargin(new Insets(0, 0, 0, 0));

			btn_stopScan.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent actionevent) {
					// TODO:
					if (rescanAction != null && rescanAction.isAlive()) {
						rescanAction.requestStopScan();
					}
				}

			});

		}
		return btn_stopScan;
	}

	protected JLabel getLbl_status() {
		if (lbl_status == null) {
			lbl_status = new JLabel("");
		}
		return lbl_status;
	}

	private JPanel getJPanel_11() {
		if (jPanel_11 == null) {
			jPanel_11 = new JPanel();
			jPanel_11.setLayout(null);
			jPanel_11.setPreferredSize(new Dimension(100, 1));
			jPanel_11.add(getLbl_fileName());
			jPanel_11.add(getLbl_fileType());
		}
		return jPanel_11;
	}

	private JLabel getLbl_fileName() {
		if (lbl_fileName == null) {
			lbl_fileName = new JLabel(FFCResource.get(FFCResource.FILE_NAME));
			lbl_fileName.setSize(119, 20);
			lbl_fileName.setLocation(0, 0);
		}
		return lbl_fileName;
	}

	private JLabel getLbl_fileType() {
		if (lbl_fileType == null) {
			lbl_fileType = new JLabel(FFCResource.get(FFCResource.FILE_TYPE));
			lbl_fileType.setSize(119, 20);
			lbl_fileType.setLocation(0, 28);
			lbl_fileType.setVisible(true);
			if (this.mode == MODE_FOLDER) {
				lbl_fileType.setVisible(false);
			}
		}
		return lbl_fileType;
	}

	private JPanel getJPanel_13() {
		if (jPanel_13 == null) {
			jPanel_13 = new JPanel();
			// jPanel_13.setBorder(BorderFactory.createLineBorder(Color.red));
			jPanel_13.setLayout(null);
			jPanel_13.setPreferredSize(new Dimension(100, 1));
			jPanel_13.add(getBtn_open());
			jPanel_13.add(getBtn_select());
			jPanel_13.add(getBtn_cancel());
		}
		return jPanel_13;
	}

	private JPanel getJPanel_12() {
		if (jPanel_12 == null) {
			jPanel_12 = new JPanel();
			jPanel_12.setLayout(new BorderLayout());
			jPanel_12.add(getTxt_fileName(), BorderLayout.NORTH);
			jPanel_12.add(getCmb_fileType(), BorderLayout.SOUTH);
		}
		return jPanel_12;
	}

	private JButton btn_open = null;

	protected JButton getBtn_open() {
		if (btn_open == null) {
			btn_open = new JButton(FFCResource.get(FFCResource.OPEN));
			btn_open.setEnabled(false);
			btn_open.setSize(38, 20);
			if (this.mode == MODE_FILE) {
				btn_open.setSize(80, 20);
			}
			btn_open.setLocation(10, 0);
			btn_open.setFocusPainted(false);
			btn_open.setMargin(new Insets(0, 0, 0, 0));

			btn_open.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent actionevent) {
					String tmpName = getTxt_fileName().getText();
					String path1 = selectedAbsolutePath + System.getProperty("file.separator") + tmpName;
					String path2 = tmpName;
					openAction(false, new String[]{path1, path2});
				}

			});
		}
		return btn_open;
	}

	private JButton btn_select = null;

	protected JButton getBtn_select() {
		if (btn_select == null) {
			btn_select = new JButton(FFCResource.get(FFCResource.SELECT));
			btn_select.setEnabled(false);
			btn_select.setSize(38, 20);
			btn_select.setLocation(52, 0);
			btn_select.setFocusPainted(false);
			btn_select.setMargin(new Insets(0, 0, 0, 0));
			btn_select.setVisible(true);
			if (this.mode == MODE_FILE) {
				btn_select.setVisible(false);
			}

			btn_select.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent actionevent) {
					String tmpName = getTxt_fileName().getText();
					String path1 = selectedAbsolutePath + System.getProperty("file.separator") + tmpName;
					String path2 = tmpName;
//					openAction(false, new String[]{path1, path2});

					setSelectedAbsolutePath(path1);
					setReturnValue(JOptionPane.OK_OPTION);
					closeDialog();
				}

			});
		}
		return btn_select;
	}

	private JTextField txt_fileName = null;

	protected JTextField getTxt_fileName() {
		if (txt_fileName == null) {
			txt_fileName = new JTextField();

			txt_fileName.getDocument().addDocumentListener(new DocumentListener() {

				public void changedUpdate(DocumentEvent e) {
					logger.debug("txt_fileName.changedUpdate ---- start");
					_set(e);
					logger.debug("txt_fileName.changedUpdate ---- end");
				}

				public void insertUpdate(DocumentEvent e) {
					logger.debug("txt_fileName.insertUpdate ---- start");
					_set(e);
					logger.debug("txt_fileName.insertUpdate ---- end");
				}

				public void removeUpdate(DocumentEvent e) {
					logger.debug("txt_fileName.removeUpdate ---- start");
					_set(e);
					logger.debug("txt_fileName.removeUpdate ---- end");
				}

			});
		}
		return txt_fileName;
	}

	private void _set(DocumentEvent e) {
		logger.debug("_set ---- start");
//		final String inputStr = getTxt_fileName().getText();
//		boolean flg = false;
//		FileItemTableModel model = (FileItemTableModel) getTableView().getModel();
//		for (int i = 0; i < model.getRowCount(); i++) {
//			FileItem fi = (FileItem) model.getRow(i);
//			if(fi.getAbsolutePath().equals(inputStr)
//					|| fi.getName().equals(inputStr)){
//				setSelectedAbsolutePath(fi.getAbsolutePath());
//				flg = true;
//				break;
//			}
//		}
//		logger.debug("_set.flg = " + flg);
//		if(flg == false){
//			if (!"".equals(inputStr)) {
//				setSelectedAbsolutePath(inputStr);
//			}
//		}
		if (e.getDocument().getLength() == 0) {
			getBtn_open().setEnabled(false);
			getBtn_select().setEnabled(false);
		} else {
			getBtn_open().setEnabled(true);
			getBtn_select().setEnabled(true);
		}
		logger.debug("_set ---- end");
	}

	private JComboBox cmb_fileType = null;

	protected JComboBox getCmb_fileType() {
		if (cmb_fileType == null) {
			cmb_fileType = new JComboBox();
			cmb_fileType.setEnabled(false);
			cmb_fileType.setVisible(true);
			if (this.mode == MODE_FOLDER) {
				cmb_fileType.setVisible(false);
			}

			for (FileFilter ff : this.fileFilters) {
				cmb_fileType.addItem(ff);
			}
			cmb_fileType.addItem(new FileFilter() {

				public boolean accept(File file) {
					return true;
				}

				@Override
				public String toString() {
					return "*.*";
				}
			});

			cmb_fileType.addItemListener(new ItemListener() {

				public void itemStateChanged(ItemEvent e) {
					if (e.getStateChange() == ItemEvent.SELECTED) {
						rescanCurrentDirectory();
					}
				}

			});

		}
		return cmb_fileType;
	}

	private JButton btn_cancel = null;

	private JButton getBtn_cancel() {
		if (btn_cancel == null) {
			btn_cancel = new JButton(FFCResource.get(FFCResource.CANCEL));
			btn_cancel.setSize(80, 20);
			btn_cancel.setLocation(10, 28);
			btn_cancel.setFocusPainted(false);
			btn_cancel.setMargin(new Insets(0, 0, 0, 0));

			btn_cancel.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent actionevent) {
					dialog.dispose();
				}

			});

		}
		return btn_cancel;
	}

	public void addChoosableFileFilter(FileFilter ff) {
		this.fileFilters.add(ff);
	}

	public void setMultiSelectionEnabled(boolean flag) {

	}

	public File getSelectedFile() {
		return new File(this.selectedAbsolutePath);
	}

	protected void setSelectedAbsolutePath(String s) {
		logger.debug("!setSelectedAbsolutePath:" + s);
		this.selectedAbsolutePath = s;
	}

	protected void setReturnValue(int value) {
		this.returnValue = value;
	}

	public static void make(File file, FileItem fi, boolean flg) {
		BufferedImage img = null;
		String type = "";
		String displayName = "";
		try {
			if (flg == false) {
				throw new Exception("SET DEF ICON");
			}
			FileSystemView sysView = FileSystemView.getFileSystemView();

			Icon icon = sysView.getSystemIcon(file);
			img = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
			Graphics g = img.getGraphics();
			icon.paintIcon(null, g, 0, 0);
			// g.drawImage(img, 0, 0, null);
			g.dispose();

			type = sysView.getSystemTypeDescription(file);

			displayName = sysView.getSystemDisplayName(file);

		} catch (Exception e1) {
			logger.error(e1);
			img = new BufferedImage(16, 16, BufferedImage.TYPE_4BYTE_ABGR);
			Graphics g = img.getGraphics();
			if (file.isFile()) {
				g.setColor(Color.white);
			} else {
				g.setColor(new Color(243, 233, 158));
			}
			g.fillRoundRect(1, 1, 14, 14, 2, 2);
			g.setColor(Color.black);
			g.drawString("?", 5, 13);
			g.drawRoundRect(1, 1, 14, 14, 2, 2);

			g.dispose();
		}

		fi.setSysDisplayName(displayName);
		fi.setIcon(img);
		fi.setType(type);
	}

	protected FileItem getSelectedItem(MouseEvent e, JComponent fileListUI) {
		FileItem fi = null;
		if (fileListUI instanceof JList) {
			JList list = (JList) listView;
			int index = list.locationToIndex(e.getPoint());
			if (index >= 0) {
				DefaultListModel model = (DefaultListModel) list.getModel();
				fi = (FileItem) model.getElementAt(index);
			}

		} else if (fileListUI instanceof JTable) {
			JTable table = (JTable) fileListUI;
			Point p = e.getPoint();
			int rowNumber = table.rowAtPoint(p);
			if (rowNumber >= 0) {
				FileItemTableModel model = (FileItemTableModel) table.getModel();
				fi = (FileItem) model.getRow(rowNumber);
			}
		}
		return fi;
	}

	/**
	 * TODO:重要的说明
	 * pcFlg=true  : JComboBox的itemStateChanged触发，不是由选择JComboBox引起的(Model变更引起的)
	 * pcFlg=false : JComboBox的itemStateChanged触发，是由选择JComboBox引起的。所以，在JComboBox的mousePressed的时候，需要把pcFlg设置成false
	 */
	private boolean pcFlg = false;

	protected void setPcFlg(boolean flg) {
		pcFlg = flg;
	}

	protected void openAction(boolean init, String aimPath) {
		openAction(init, new String[]{aimPath});
	}

	protected void openAction(boolean init, String[] pathArray) {
		pcFlg = true;
		OpenFileAction action = new OpenFileAction(getTableView(), init, pathArray, FastFileChooser.this, pcFlg);
		action.start();
	}

	protected void updateStatus(String s) {
		getLbl_status().setText(s);
	}

	protected void updateUserHome() {
		DefaultComboBoxModel model = this.getJpUserHome().getModel();
		boolean f = false;
		for (int i = 0; i < model.getSize(); i++) {
			FileItem fi = (FileItem) model.getElementAt(i);
			if (fi.getAbsolutePath().equals(selectedAbsolutePath)) {
				// will fire contentsChanged
				model.setSelectedItem(null);
				model.setSelectedItem(fi);
				f = true;
				break;
			}
		}
		if (f == false) {
			// will fire contentsChanged
			model.setSelectedItem(null);
		}
	}
}